package com.innovation.ic.cyz.base.service.cyz.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.innovation.ic.b1b.framework.util.IdUtil;
import com.innovation.ic.cyz.base.mapper.cyz.VideoMapper;
import com.innovation.ic.cyz.base.model.cyz.User;
import com.innovation.ic.cyz.base.model.cyz.VidBrand;
import com.innovation.ic.cyz.base.model.cyz.VidCategory;
import com.innovation.ic.cyz.base.model.cyz.VidRel;
import com.innovation.ic.cyz.base.model.cyz.VidTag;
import com.innovation.ic.cyz.base.model.cyz.VidType;
import com.innovation.ic.cyz.base.model.cyz.Video;
import com.innovation.ic.cyz.base.pojo.constant.GeneralStatus;
import com.innovation.ic.cyz.base.pojo.constant.VidApproveStatus;
import com.innovation.ic.cyz.base.pojo.constant.VidRelModule;
import com.innovation.ic.cyz.base.pojo.global.ApiPageResult;
import com.innovation.ic.cyz.base.pojo.global.ServiceResult;
import com.innovation.ic.cyz.base.pojo.variable.cyz.avd.AvdUserPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidBrandPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidCategoryPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidDetailPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidListPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidTagPojo;
import com.innovation.ic.cyz.base.pojo.variable.cyz.video.VidTypePojo;
import com.innovation.ic.cyz.base.service.cyz.VideoService;
import com.innovation.ic.cyz.base.vo.cyz.video.VidApproveVo;
import com.innovation.ic.cyz.base.vo.cyz.video.VidListVo;
import com.innovation.ic.cyz.base.vo.cyz.video.VideoAddVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class VideoServiceImpl extends ServiceImpl<VideoMapper, Video> implements VideoService {

    @Resource
    private ServiceHelper serviceHelper;

    @Override
    public ServiceResult<List<VidCategoryPojo>> getCategories() {
        QueryWrapper<VidCategory> categoryWrapper = new QueryWrapper<>();
        categoryWrapper.lambda().eq(VidCategory::getStatus, GeneralStatus.NORMAL);
        categoryWrapper.orderByAsc("order_index");
        List<VidCategory> categoryList = serviceHelper.getVidCategoryMapper().selectList(categoryWrapper);

        List<VidCategoryPojo> list = categoryList.stream().map(item -> {
            VidCategoryPojo pojo = new VidCategoryPojo();
            pojo.setId(item.getId());
            pojo.setName(item.getName());
            return pojo;
        }).collect(Collectors.toList());

        ServiceResult<List<VidCategoryPojo>> result = new ServiceResult<>();
        result.setResult(list);
        result.setSuccess(Boolean.TRUE);
        result.setMessage(ServiceResult.SELECT_SUCCESS);
        return result;
    }

    @Override
    public ServiceResult<List<VidBrandPojo>> getBrands() {
        QueryWrapper<VidBrand> brandWrapper = new QueryWrapper<>();
        brandWrapper.lambda().eq(VidBrand::getStatus, GeneralStatus.NORMAL);
        brandWrapper.orderByAsc("order_index");
        List<VidBrand> brandList = serviceHelper.getVidBrandMapper().selectList(brandWrapper);

        List<VidBrandPojo> pojoList = brandList.stream().map(item -> {
            VidBrandPojo pojo = new VidBrandPojo();
            pojo.setId(item.getId());
            pojo.setName(item.getName());
            return pojo;
        }).collect(Collectors.toList());

        ServiceResult<List<VidBrandPojo>> result = new ServiceResult<>();
        result.setSuccess(Boolean.TRUE);
        result.setResult(pojoList);
        result.setMessage(ServiceResult.SELECT_SUCCESS);
        return result;
    }

    @Override
    public ServiceResult<List<VidTypePojo>> getTypes() {
        QueryWrapper<VidType> typeWrapper = new QueryWrapper<>();
        typeWrapper.lambda().eq(VidType::getStatus, GeneralStatus.NORMAL);
        typeWrapper.orderByAsc("order_index");
        List<VidType> typeList = serviceHelper.getTypeMapper().selectList(typeWrapper);
        List<VidTypePojo> pojoList = typeList.stream().map(item -> {
            VidTypePojo pojo = new VidTypePojo();
            pojo.setId(item.getId());
            pojo.setName(item.getName());
            return pojo;
        }).collect(Collectors.toList());

        ServiceResult<List<VidTypePojo>> result = new ServiceResult<>();
        result.setResult(pojoList);
        result.setSuccess(Boolean.TRUE);
        result.setMessage(ServiceResult.SELECT_SUCCESS);
        return result;
    }

    @Override
    public ServiceResult<List<VidTagPojo>> getTags() {
        QueryWrapper<VidTag> tagWrapper = new QueryWrapper<>();
        tagWrapper.lambda().eq(VidTag::getStatus, GeneralStatus.NORMAL);
        tagWrapper.orderByAsc("order_index");
        List<VidTag> tagList = serviceHelper.getTagMapper().selectList(tagWrapper);
        List<VidTagPojo> pojoList = tagList.stream().map(item -> {
            VidTagPojo pojo = new VidTagPojo();
            pojo.setId(item.getId());
            pojo.setName(item.getName());
            return pojo;
        }).collect(Collectors.toList());

        ServiceResult<List<VidTagPojo>> result = new ServiceResult<>();
        result.setResult(pojoList);
        result.setSuccess(Boolean.TRUE);
        result.setMessage(ServiceResult.SELECT_SUCCESS);
        return result;
    }

    @Override
    public ServiceResult<ApiPageResult<VidListPojo>> getList(VidListVo param, Integer pageIndex, Integer pageSize) {
        Page<Video> p = new Page<>(pageIndex, pageSize);
        IPage<VidListPojo> videos = serviceHelper.getVideoMapper().getList(p, param.getTitle(), param.getTag(),
                param.getCategories(), param.getBrands(), param.getTypes(),
                param.getOrderByName(), param.getOrderByType());

        List<VidListPojo> data = videos.getRecords().stream().map(item -> {

            //设置前缀
            if (item.getCover() != null && !item.getCover().isEmpty()) {
                item.setCover(serviceHelper.getFtpAccountConfig().getImageUrlBasePath() + item.getCover());
            }

            return item;
        }).collect(Collectors.toList());

        ApiPageResult<VidListPojo> pageResult = new ApiPageResult<>();
        pageResult.setList(data);
        pageResult.setPageNum(pageIndex);
        pageResult.setPageSize(pageSize);
        pageResult.setTotal(videos.getTotal());
        pageResult.setTotalPage(Integer.valueOf(String.valueOf(videos.getPages())));
        ServiceResult<ApiPageResult<VidListPojo>> serviceResult = new ServiceResult<>();
        serviceResult.setResult(pageResult);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    @Override
    public ServiceResult<VidDetailPojo> getDetail(Long id) {
        VidDetailPojo pojo = new VidDetailPojo();
        Video video = serviceHelper.getVideoMapper().selectById(id);

        pojo.setId(video.getId());
        pojo.setTitle(video.getTitle());
        pojo.setCover(video.getCover());
        pojo.setDescription(video.getDescription());
        pojo.setParagraph(video.getParagraph());
        pojo.setViewNum(video.getViewNum());
        pojo.setCreateDate(video.getCreateDate());

        // 给封面地址添加url前缀
        if (video.getCover() != null && !video.getCover().isEmpty()) {
            pojo.setCover(serviceHelper.getFtpAccountConfig().getImageUrlBasePath() + video.getCover());
        }

        // 视频添加前缀
        if (video.getVideo() != null && !video.getVideo().isEmpty()) {
            pojo.setVideo(serviceHelper.getHostParamsConfig().getCyzVideo() + video.getVideo());
        }

        // 查询并填写作者信息
        User user = serviceHelper.getUserMapper().selectById(video.getCreatorId());
        if (user == null) {
            user = new User();
        }
        String avatar = null;
        if (user.getAvatar() != null) {
            avatar = serviceHelper.getFtpAccountConfig().getImageUrlBasePath() + user.getAvatar();
        }
        //添加标签
        List<VidTagPojo> vidTagPojoList = serviceHelper.getTagMapper().findByVidTagPojo(id);
        pojo.setTags(vidTagPojoList);
        AvdUserPojo userPojo = new AvdUserPojo();
        userPojo.setCreatorId(user.getId());
        userPojo.setCreatorName(user.getUsername());
        userPojo.setCreatorAvatar(avatar);
        pojo.setUser(userPojo);

        ServiceResult<VidDetailPojo> result = new ServiceResult<>();
        result.setSuccess(Boolean.TRUE);
        result.setResult(pojo);
        result.setMessage(ServiceResult.SELECT_SUCCESS);
        return result;
    }

    @Override
    public ServiceResult<Long> add(VideoAddVo vo, String userId) {
        Long vid = IdUtil.snowflakeNextId();
        Video video = new Video();
        video.setId(vid);
        video.setTitle(vo.getTitle());
        video.setCover(vo.getCover());
        video.setVideo(vo.getVideo());
        video.setDescription(vo.getDescription());
        video.setParagraph(vo.getParagraph());
        video.setViewNum(0);
        video.setLikeNum(0);
        video.setCollectNum(0);
        video.setApproveStatus((vo.getIsDraft() != null && vo.getIsDraft())
                ? VidApproveStatus.Draft : VidApproveStatus.UnApprove);
        video.setStatus(GeneralStatus.NORMAL);
        video.setCreatorId(userId);
        video.setCreateDate(new Date());

        //视频映射表
        List<VidRel> relList = new ArrayList<>();
        relList.addAll(convertToRelList(VidRelModule.Category, vid, vo.getCategoryIds()));
        relList.addAll(convertToRelList(VidRelModule.Tag, vid, vo.getTagIds()));
        relList.addAll(convertToRelList(VidRelModule.Brand, vid, vo.getBrandIds()));
        relList.addAll(convertToRelList(VidRelModule.Type, vid, vo.getTypeIds()));

        serviceHelper.getVideoMapper().insert(video);
        serviceHelper.getRelMapper().insertBatchSomeColumn(relList);

        ServiceResult<Long> result = new ServiceResult<>();
        result.setResult(vid);
        result.setMessage(ServiceResult.INSERT_SUCCESS);
        result.setSuccess(Boolean.TRUE);
        return result;
    }

    @Override
    public ServiceResult<Long> edit(VideoAddVo video, String userId) {
        UpdateWrapper<Video> uwVideo = new UpdateWrapper<>();
        uwVideo.lambda().eq(Video::getId, video.getId());
        uwVideo.lambda().set(Video::getTitle, video.getTitle());
        uwVideo.lambda().set(Video::getVideo, video.getVideo());
        uwVideo.lambda().set(Video::getCover, video.getCover());
        uwVideo.lambda().set(Video::getDescription, video.getDescription());
        uwVideo.lambda().set(Video::getParagraph, video.getParagraph());
        uwVideo.lambda().set(Video::getApproveStatus, (video.getIsDraft() != null && video.getIsDraft())
                ? VidApproveStatus.Draft : VidApproveStatus.UnApprove);
        uwVideo.lambda().set(Video::getModifierId, userId);
        uwVideo.lambda().set(Video::getModifyDate, new Date());

        List<VidRel> relList = new ArrayList<>();
        relList.addAll(convertToRelList(VidRelModule.Category, video.getId(), video.getCategoryIds()));
        relList.addAll(convertToRelList(VidRelModule.Tag, video.getId(), video.getTagIds()));
        relList.addAll(convertToRelList(VidRelModule.Brand, video.getId(), video.getBrandIds()));
        relList.addAll(convertToRelList(VidRelModule.Type, video.getId(), video.getTypeIds()));

        //更新
        serviceHelper.getVideoMapper().update(null, uwVideo);

        QueryWrapper<VidRel> qwRel = new QueryWrapper<>();
        qwRel.lambda().eq(VidRel::getVidId, video.getId());
        serviceHelper.getRelMapper().delete(qwRel);
        serviceHelper.getRelMapper().insertBatchSomeColumn(relList);

        ServiceResult<Long> serviceResult = new ServiceResult<>();
        serviceResult.setResult(video.getId());
        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    @Override
    public ServiceResult approved(VidApproveVo vo) {
        UpdateWrapper<Video> videoUpdateWrapper = new UpdateWrapper<>();
        videoUpdateWrapper.lambda().eq(Video::getId, vo.getVid());
        videoUpdateWrapper.lambda().set(Video::getApproveStatus, VidApproveStatus.Approved);
        serviceHelper.getVideoMapper().update(null, videoUpdateWrapper);

        ServiceResult serviceResult = new ServiceResult();
        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    @Override
    public List<Video> findByPage(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum,pageSize);
        QueryWrapper<Video> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("id");
        return serviceHelper.getVideoMapper().selectList(queryWrapper);
    }

    /**
     * 将VidRelIds转换为VidRelList
     *
     * @param module
     * @param vid
     * @param relIds
     * @return
     */
    private List<VidRel> convertToRelList(Integer module, Long vid, List<Long> relIds) {
        List<VidRel> relList = new ArrayList<>();
        for (Long relId : relIds) {
            VidRel rel = new VidRel();
            rel.setId(IdUtil.snowflakeNextId());
            rel.setModule(module);
            rel.setVidId(vid);
            rel.setVidRelId(relId);
            relList.add(rel);
        }
        return relList;
    }
}